import vlc
from PySide6.QtCore import QObject, Signal

from src.utils.debug_tools import print_debug


# os.environ['VLC_PLUGIN_PATH'] = "3rdparty/vlc-3.0.21/plugins"


class VlcMediaPlayer(QObject):
    # Signals to emit status updates
    mediaStateChanged = Signal(str)
    mediaPositionChanged = Signal(float)
    mediaVolumeChanged = Signal(int)
    errorOccurred = Signal()

    def __init__(self, parent=None):
        super().__init__(parent)
        self.instance = vlc.Instance('--no-video', "--quiet")  # No video output, no console
        self._player = self.instance.media_player_new()
        self.event_manager = self._player.event_manager()
        self.event_manager.event_attach(vlc.EventType.MediaPlayerPlaying, self._on_playing)
        self.event_manager.event_attach(vlc.EventType.MediaPlayerPaused, self._on_paused)
        self.event_manager.event_attach(vlc.EventType.MediaPlayerStopped, self._on_stopped)
        self.event_manager.event_attach(vlc.EventType.MediaPlayerBuffering, self._on_buffering)
        self.event_manager.event_attach(vlc.EventType.MediaPlayerTimeChanged, self._on_time_changed)
        self.event_manager.event_attach(vlc.EventType.MediaPlayerEndReached, self._on_end_reached)
        self.event_manager.event_attach(vlc.EventType.MediaPlayerEncounteredError, self._errorOccurred)

    def setMute(self, mute):
        self._player.audio_toggle_mute()

    def hasMedia(self):
        return self._player.get_media() is not None

    def _errorOccurred(self, event: vlc.Event):
        self.errorOccurred.emit()

    def destroyPlayer(self):
        self.event_manager.event_detach(vlc.EventType.MediaPlayerTimeChanged)
        self.event_manager.event_detach(vlc.EventType.MediaPlayerPlaying)
        self.event_manager.event_detach(vlc.EventType.MediaPlayerPaused)
        self.event_manager.event_detach(vlc.EventType.MediaPlayerStopped)
        self.event_manager.event_detach(vlc.EventType.MediaPlayerEndReached)
        self._player.release()
        self.instance.release()

    def setMediaUrl(self, media_url):
        media = self.instance.media_new(media_url)
        media.add_option('http-user-agent=Mozilla/5.0')
        media.add_option('http-referrer=https://www.bilibili.com/')
        self._player.set_media(media)
        media.parse()

    def getCurrentTime(self):
        return self._player.get_time() / 1000.0

    def getDuration(self):
        if self._player.get_media():
            return self._player.get_length() / 1000.0

    def play(self):
        if self._player.get_media():
            self._player.play()

    def pause(self):
        if self._player.is_playing():
            self._player.pause()

    def stop(self):
        if self._player.is_playing():
            self._player.stop()

    def isPlaying(self):
        return self._player.is_playing()

    def setPosition(self, position):
        if self._player.get_media():
            self._player.set_position(position)
        self.mediaPositionChanged.emit(position)

    def setVolume(self, volume):
        self._player.audio_set_volume(volume)
        self.mediaVolumeChanged.emit(volume)

    def getVolume(self):
        return self._player.audio_get_volume()

    def release(self):
        self.stop()
        self._player.release()
        self.instance.release()

    def _on_playing(self, event):
        self.mediaStateChanged.emit("Playing")

    def _on_paused(self, event):
        self.mediaStateChanged.emit("Paused")

    def _on_stopped(self, event):
        self.mediaStateChanged.emit("Stopped")

    def _on_buffering(self, event):
        self.mediaStateChanged.emit("Buffering")

    def _on_time_changed(self, event):
        position = self._player.get_position()
        self.mediaPositionChanged.emit(position)

    def _on_end_reached(self, event):
        self.mediaStateChanged.emit("Ended")
